package xyz.xmh.executor;

import org.springframework.util.ObjectUtils;
import xyz.xmh.cache.Cache;
import xyz.xmh.pojo.entity.BaseItem;
import xyz.xmh.pojo.enums.CategoryEnum;
import xyz.xmh.pojo.enums.CheckNameEnum;
import xyz.xmh.pojo.request.file.ListRequest;
import xyz.xmh.pojo.request.file.MultiDownloadUrlRequest;
import xyz.xmh.pojo.request.file.SearchRequest;
import xyz.xmh.pojo.request.file.UpdateRequest;
import xyz.xmh.pojo.response.file.*;

import java.nio.file.OpenOption;
import java.nio.file.Path;

/**
 * 2021/10/26 14:35 星期二<br/>
 *
 * @author xuMingHai
 */
public class CacheExecutor implements Executor {

    private final Cache cache;

    private final Executor executor;

    public CacheExecutor(Cache cache, Executor executor) {
        this.cache = cache;
        this.executor = executor;
    }

    @Override
    public ListResponse list() {
        return list(new ListRequest());
    }

    @Override
    public ListResponse list(ListRequest listRequest) {
        final String key = "list_" + listRequest.hashCode();
        final Object o = cache.get(key);
        ListResponse listResponse;

        if (ObjectUtils.isEmpty(o)) {
            listResponse = executor.list(listRequest);
            cache.put(key, listResponse);
        } else {
            listResponse = (ListResponse) o;
        }

        return listResponse;
    }

    @Override
    public SearchResponse search(String fileName) {
        final SearchRequest searchRequest = new SearchRequest();
        searchRequest.setQuery(fileName);
        return search(searchRequest);
    }

    @Override
    public SearchResponse search(String fileName, CategoryEnum categoryEnum) {
        final SearchRequest searchRequest = new SearchRequest();
        searchRequest.setQuery(fileName, categoryEnum);
        return search(searchRequest);
    }

    @Override
    public SearchResponse search(SearchRequest searchRequest) {
        final String key = "search_" + searchRequest.hashCode();
        final Object o = cache.get(key);
        SearchResponse searchResponse;

        if (ObjectUtils.isEmpty(o)) {
            searchResponse = executor.search(searchRequest);
            cache.put(key, searchResponse);
        } else {
            searchResponse = (SearchResponse) o;
        }

        return searchResponse;
    }

    @Override
    public BaseItem get(String fileId) {
        final String key = "get_" + fileId;
        final Object o = cache.get(key);
        BaseItem baseItem;

        if (ObjectUtils.isEmpty(o)) {
            baseItem = executor.get(fileId);
            cache.put(key, baseItem);
        } else {
            baseItem = (BaseItem) o;
        }

        return baseItem;
    }

    @Override
    public DownloadUrlResponse getDownloadUrl(String fileId) {
        return executor.getDownloadUrl(fileId);
    }

    @Override
    public long downloadFile(String fileId, Path path, OpenOption... openOptions) {
        return executor.downloadFile(fileId, path, openOptions);
    }

    @Override
    public MultiDownloadUrlResponse getMultiDownloadUrl(MultiDownloadUrlRequest multiDownloadUrlRequest) {
        return executor.getMultiDownloadUrl(multiDownloadUrlRequest);
    }

    @Override
    public long multiDownloadFile(MultiDownloadUrlRequest multiDownloadUrlRequest, Path path, OpenOption... openOptions) {
        return executor.multiDownloadFile(multiDownloadUrlRequest, path, openOptions);
    }

    @Override
    public CreateFolderResponse createFolder(String parentFileId, String name, CheckNameEnum checkNameEnum) {
        cache.clear();
        return executor.createFolder(parentFileId, name, checkNameEnum);
    }

    @Override
    public CreateFolderResponse createFolder(String parentFileId, String name) {
        cache.clear();
        return executor.createFolder(parentFileId, name);
    }

    @Override
    public CreateFolderResponse createFolder(String name) {
        cache.clear();
        return executor.createFolder(name);
    }

    @Override
    public CreateFileResponse uploadFile(String parentFileId, Path path, CheckNameEnum checkNameEnum) {
        cache.clear();
        return executor.uploadFile(parentFileId, path, checkNameEnum);
    }

    @Override
    public CreateFileResponse uploadFile(String parentFileId, Path path) {
        cache.clear();
        return executor.uploadFile(parentFileId, path);
    }

    @Override
    public CreateFileResponse uploadFile(Path path) {
        cache.clear();
        return executor.uploadFile(path);
    }

    @Override
    public boolean trash(String fileId) {
        cache.clear();
        return executor.trash(fileId);
    }

    @Override
    public BaseItem update(UpdateRequest updateRequest) {
        cache.clear();
        return executor.update(updateRequest);
    }

    @Override
    public BaseItem update(String fileId, String name) {
        cache.clear();
        return executor.update(fileId, name);
    }
}
